package src.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.HashMap;


import src.driver.Driver;
import src.driver.PlayerObjectData;
import src.model.gameWorld.MapTileConfiguration;
import src.view.ViewHandler.DisplayType;
import src.view.ViewHandler.ImageType;

/**
 * <b>Overview</b>
 * The StartupViewport is the first screen the user sees.  It allows a user to see credits, start a new game, or exit the program.
 *
 * <b>Responsibilities</b>
 * Display credits, allow a user to exit, and accept the relevant inputs to start a new game.
 *
 * <b>Collaborators</b>
 * Drawable - The Drawable object displays the viewport to the screen.
 *
 * <b>Implementor</b> - Bruce
 * <b>Tester</b> - Tim
 *
 * @author Bruce
 */
public class StartupViewport extends Viewport
{
	private String name = "";

	private Color color = Color.WHITE;

	private HashMap<String, Color> players = new HashMap<String, Color>();

	private enum State
	{
		MAIN, CREDIT, PLAYER
	}

	private State state = State.MAIN;

	private void setState(State state)
	{
		this.state = state;
		refresh(DisplayType.STARTUP);
	}

	/**
	 * Creates a new StartupViewport.
	 *
	 * @param canvas the Drawable to draw this viewport to.
	 */
	public StartupViewport(ViewHandler vh, Drawable canvas){
		super(vh, canvas, DisplayType.STARTUP);

		// Background
		int x, y;
		AffineTransform at = new AffineTransform();
		BufferedImage image;

		image = getImage(ImageType.SHIP);
		x = image.getWidth();
		y = image.getHeight();
		at.scale((double)getWidth() / x, (double)getHeight() / y);
		getCanvas().drawImage(image, at, null);
	}

	/* (non-Javadoc)
	 * @see src.view.Viewport#draw()
	 */
	@Override
	protected void draw()
	{
		BufferedImage image;
		image = getImage(ImageType.PARCHMENT);
		getCanvas().drawImage(image, 0, 0, null);
		int x = image.getWidth();

		switch(state)
		{
			case MAIN:
			{
				drawString("New Game", 30, 80);
				drawString("Credits", 30, 110);
				drawString("Exit", 30, 140);
				break;
			}
			case CREDIT:
			{
				drawString("The Mastermind:", 30, 75);
				drawString("Brent Moffit", 40, 95);
				drawString("The Maniac:", 30, 125);
				drawString("Bruce Santier", 40, 145);
				drawString("The Other Dude:", 30, 175);
				drawString("Tristan Lohman", 40, 195);
				drawString("Mr. VIM:", 30, 225);
				drawString("Tim Smith", 40, 245);
				break;
			}
			case PLAYER:
			{
				try
				{
					getCanvas().drawImage(image, (getWidth() - x), 0, null);

					// Colors
					image = getImage(ImageType.SELECTION);
					getCanvas().drawImage(image, colorX(color), colorY(color), null);

					image = getImage(ImageType.WHITE);
					getCanvas().drawImage(image, 40, 160, null);
					image = getImage(ImageType.BLACK);
					getCanvas().drawImage(image, 80, 160, null);
					image = getImage(ImageType.RED);
					getCanvas().drawImage(image, 120, 160, null);
					image = getImage(ImageType.GREEN);
					getCanvas().drawImage(image, 160, 160, null);

					image = getImage(ImageType.ORANGE);
					getCanvas().drawImage(image, 40, 200, null);
					image = getImage(ImageType.BLUE);
					getCanvas().drawImage(image, 80, 200, null);
					image = getImage(ImageType.YELLOW);
					getCanvas().drawImage(image, 120, 200, null);
					image = getImage(ImageType.PINK);
					getCanvas().drawImage(image, 160, 200, null);

					if(players.size() >= 2)
					{
						image = getImage(ImageType.BUTTON);
						getCanvas().drawImage(image, 10, getHeight() - image.getHeight() - 40, null);
						image = getImage(ImageType.HEX);
						getCanvas().drawImage(image, 150, getHeight() - image.getHeight() - 20, null);
					}
				}
				catch(Exception e) {e.printStackTrace();}

				drawString("Enter a pirate name:", 30, 75);
				drawString(name + "_", 40, 95);
				drawString("Choose a pirate color:", 30, 145);

				drawString("Registered players:", getWidth() - 210, 80);
				int y = 0;
				for(String n : players.keySet())
					drawString(n, getWidth() - 200, (++y * 20) + 90, Color.BLACK, players.get(n));
			}
		}
	}

	/* (non-Javadoc)
	 * @see src.view.Viewport#getResizeDimension()
	 */
	@Override
	protected Dimension getResizeDimension()
	{
		return getCanvasDimensions();
	}

	/* (non-Javadoc)
	 * @see src.view.Viewport#getResizePoint()
	 */
	@Override
	protected Point2D getResizePoint()
	{
		return Point2D.origin();
	}

	protected void keyTyped(KeyEvent e)
	{
		if(state == State.PLAYER)
		{
			if(e.getKeyCode() == KeyEvent.VK_ENTER)
				registerName();
			else if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
			{
				if(name.length() > 0)
					name = name.substring(0, name.length() - 1);
			}
			else if(e.getKeyCode() == KeyEvent.VK_SHIFT)
			{}
			else if(name.length() < 20)
				name = name + e.getKeyChar();

			refresh(DisplayType.STARTUP);
		}
	}

	private void registerName()
	{
		players.put(name, color);
		name = "";
		refresh(DisplayType.STARTUP);
	}

	protected void click(Point p)
	{
		int x = (int)p.getX();
		int y = (int)p.getY();

		switch(state)
		{
			case CREDIT:
			{
				setState(State.MAIN);
				break;
			}
			case MAIN:
			{
				if(x >= 35 && x <= 115 && y >= 90 && y <= 105)
					setState(State.PLAYER);
				if(x >= 35 && x <= 85 && y >= 120 && y <= 135)
					setState(State.CREDIT);
				if(x >= 35 && x <= 65 && y >= 150 && y <= 165)
					System.exit(0);
				break;
			}
			case PLAYER:
			{
				if(players.size() >= 2)
				{
					if(x >= 15 && x <= 115 && y >= getHeight() - 50 && y <= getHeight() - 15)
					{
						int i = 0;
						PlayerObjectData [] data = new PlayerObjectData[players.size()];
						for(String name : players.keySet())
							data[i++] = new PlayerObjectData(name, players.get(name), "data/controller/default");
						players.clear();
						Driver.startGame(data, MapTileConfiguration.Octagonal);
					}
					else if(x >= 200 && x <= 300 && y >= getHeight() - 100 && y <= getHeight() - 15)
					{
						int i = 0;
						PlayerObjectData [] data = new PlayerObjectData[players.size()];
						for(String name : players.keySet())
							data[i++] = new PlayerObjectData(name, players.get(name), "data/controller/default");
						players.clear();
						Driver.startGame(data, MapTileConfiguration.Hexagonal);
					}
				}

				Color [] colors = {Color.BLACK, Color.BLUE, Color.WHITE, Color.ORANGE, Color.YELLOW, Color.RED, Color.PINK, Color.GREEN};
				for(Color c : colors)
					if(x >= colorX(c) && x <= colorX(c) + 40 && y >= colorY(c) + 40 && y <= colorY(c) + 80)
					{
						color = c;
						refresh(DisplayType.STARTUP);
						break;
					}
				break;
			}
		}
	}

	private int colorX(Color color)
	{
		if(color.equals(Color.WHITE) || color.equals(Color.ORANGE))
			return 32;
		else if(color.equals(Color.BLACK) || color.equals(Color.BLUE))
			return 72;
		else if(color.equals(Color.RED) || color.equals(Color.YELLOW))
			return 112;
		else
			return 152;
	}

	private int colorY(Color color)
	{
		if(color.equals(Color.WHITE) || color.equals(Color.BLACK) || color.equals(Color.RED) || color.equals(Color.GREEN))
			return 152;
		return 192;
	}

	public String toString()
	{
		return "Startup";
	}
}